home *** CD-ROM | disk | FTP | other *** search
- // copying
- // Copyright (C) 1991 David Stoutamire (daves@alpha.ces.cwru.edu)
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, version 2.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program (file "COPYING"); if not, write to the Free
- // Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- #define MAINFILE
- #include "iku.h"
-
- void foreachfile(String files, Stringfuncptr f) {
- // Call f for each file expanded by string files.
- // "allgames" gets translated to value of allgames, and
- // "forever" does allgames over and over.
- int forever=0;
- if (files=="allgames")
- files=allgames;
- else if (files=="forever") {
- forever=1;
- files=allgames;
- }
- do {
- #ifndef IRIX
- FILE* pd=popen((char*)("ls -1 "+files),"r");
- File ff(pd);
- int count=0;
- while (!ff.eof()) {
- char *cp;
- ff.gets(&cp);
- if (ff.eof()&&count==0)
- fatal("Could not find file(s): "+files);
- #else /* IRIX */
- FILE* pd=popen((char*)("cd games; ls "+files),"r");
- int count=0;
- while (!feof(pd)) {
- char cp[1000];
- if (fgets(cp,1000,pd)==NULL) {
- if (count==0)
- fatal("Could not find file(s): "+files);
- else
- break;
- }
- cp[strlen(cp)-1]='\0';
- #endif /* IRIX */
- count++;
- String s(cp);
- if (s!="")
- f(s);
- #ifdef IRIX
- free(cp);
- #endif /* IRIX */
- }
- pclose(pd);
- } while (forever);
- }
-
- static Opponent *optostudy; // for communication with dostudy
- void dostudy(String& f) {
- // Study game f: call learn for each move in the game
- // global "optostudy" is the opponent which this affects
- Game g(f);
- if (evalfile!="nofile")
- system((char*)("echo EVENT >"+evalfile));
- for (int i=0;i<g.nummoves;i++) {
- optostudy->study(g.snapshot(i),g.moves[i]);
- }
- if (dolearn)
- optostudy->docheckpt(); // sync with disk after each game
- }
-
- const int syma(int a,int b,int i) {
- // compute a' for symmetry i given a and b as offsets
- switch (i) {
- case 0:
- return(a);
- case 1:
- return(a);
- case 2:
- return(-a);
- case 3:
- return(-a);
- case 4:
- return(b);
- case 5:
- return(b);
- case 6:
- return(-b);
- case 7:
- return(-b);
- default:
- fatal("Error in syma switch.");
- }
- }
-
- const int symb(int a,int b,int i) {
- // compute b' for symmetry i given a and b as offsets
- switch (i) {
- case 0:
- return(b);
- case 1:
- return(-b);
- case 2:
- return(-b);
- case 3:
- return(b);
- case 4:
- return(a);
- case 5:
- return(-a);
- case 6:
- return(-a);
- case 7:
- return(a);
- default:
- fatal("Error in symb switch.");
- }
- }
-
- String nextarg() {
- // returns next argument from command line; fatal if no more
- global_argv++;
- global_argc--;
- if (global_argc>0)
- return(String(*global_argv));
- else
- fatal("Not enough command line args.");
- }
-
- void verify(String& s) {
- // verify that the file s is internally consistent
- cout << "Verifying " << s << "... ";
- cout.flush();
- Game* g=new Game(s);
- delete g;
- cout << "Ok.\n";
- }
-
- main(int argc, char **argv){
- #ifndef IRIX
- // This stuff is all just personal preference - you may want to change.
- struct rlimit rl;
- getrlimit(RLIMIT_STACK,&rl);
- rl.rlim_cur=2500000;
- setrlimit(RLIMIT_STACK,&rl); // needs lots o' stack
- getrlimit(RLIMIT_RSS,&rl);
- rl.rlim_cur=1000000;
- setrlimit(RLIMIT_RSS,&rl); // be nice - ask for 1 meg. resident
- getrlimit(RLIMIT_CORE,&rl);
- rl.rlim_cur=1;
- setrlimit(RLIMIT_CORE,&rl); // cores will probably be too big
- #endif /* IRIX */
-
- // read in command line args and do whatever.
- global_argv=argv;
- global_argc=argc;
-
- while (global_argc>1) {
- String s=nextarg();
- if (s=="play")
- playgame();
- else if (s=="study")
- study();
- else if (s=="help")
- system("cat iku.help");
- else if (s=="abort")
- shouldabort=true;
- else if (s=="evalfile")
- evalfile=nextarg();
- else if (s=="verify")
- foreachfile(nextarg(),verify);
- else if (s=="postscriptdir")
- postscriptdir=nextarg();
- else if (s=="nolearn")
- dolearn=false;
- else
- fatal("Unrecognized command: "+s);
- }
- }
-
- volatile void fatal(String errmsg) {
- // Ticket straight to hell when program dies.
- cout << errmsg << "\n";
- if (shouldabort==true) {
- cout << "Aborting...\n";
- abort();
- }
- else {
- cout << "Exiting...\n";
- exit(1);
- }
- }
-
- void playgame() {
- // start up two opponents and play a game. Never returns.
- Opponent *bl=makeopponent(), *wh=makeopponent();
- Board goban;
- Move m;
- dribble=nextarg();
-
- if (dribble!="nofile")
- system((char*)("echo EVENT >"+dribble));
- loop {
- if (goban.turntoplay==black)
- m=bl->getmove(goban);
- else
- m=wh->getmove(goban);
-
- if (goban.islegalmove(m))
- goban.applymove(m);
- else
- fatal("Playgame saw bad move: "+m.str());
-
- if (dribble!="nofile") {
- FILE *fp=fopen((char*)dribble,"a");
- fprintf(fp,"%c %d ",(goban.turntoplay==blackstone)?'W':'B',goban.movenum-1);
- fprintf(fp,"%s\n",(char *)m.str());
- fclose(fp);
- }
- }
- }
-
- void study() {
- // start opponent and make it study file(s) from command line.
- optostudy=makeopponent();
- String s=nextarg();
- foreachfile(s,dostudy);
- }
-
- void getnum(int& what) {
- // get a number from command line
- String s=nextarg();
- what=atoi(s);
- if (what==0&&s!="0")
- fatal("Needed a number, but got: "+s);
- }
-
- void takescore(int i, float f, int compress=1) {
- // do something with the score, such a print it out. If compress!=1,
- // then take average.
- if (dontprint)
- return;
- static int count=0;
- static float sum=0.0;
- count++;
- sum+=f;
- if (count==compress) {
- cout << form("%d %4.3f\n",i,sum/count);
- count=0;
- sum=0.0;
- }
- }
-
- int rotate(int a, int p) {
- // used by hashpjw.
- for (int i=0;i<(p>?(-p))%31;i++)
- if (a&0x40000000)
- a=(a<<1)|0x1;
- else
- a<<=1;
- return a;
- }
-
- unsigned int hashpjw(const char* x) {
- // My own hash function. This seemed to work well; you may wish
- // to substitute something else. This is important for HashOpponents.
- int h = 0;
- while (*x != 0)
- h = rotate(h,h)^(*(x++));
- return (unsigned) h;
- }
-